package com.cxc.config;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.cxc.entity.DbConfigration;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 陈先冲
 * @date 2023/5/12
 */

@Component
public class DynamicDataSource extends AbstractRoutingDataSource {
    public final static String JDBC_CONNECT_PARAM = "?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true";

    static RedissonClient redissonClient;
    @Autowired
    public void setRedisCache(RedissonClient redissonClient) {
        DynamicDataSource.redissonClient = redissonClient;
    }

    /**
     * 数据源MAP
     */
    public static final Map<String, DataSource> DATA_SOURCES_MAP = new ConcurrentHashMap<>(64);

    /**
     * 当前登录人
     */
    private static final ThreadLocal<String> LOGIN_NAME_KEY = new ThreadLocal<>();


    @Override
    protected Object determineCurrentLookupKey() {
        return LOGIN_NAME_KEY.get();
    }

    @Override
    @NonNull
    public DataSource determineTargetDataSource() {
        try {
            String loginName = LOGIN_NAME_KEY.get();
            DbConfigration dbConfigration = (DbConfigration)redissonClient.getMap("sites").get(loginName.toLowerCase());
            String host = dbConfigration.getHost();
            String dbName = dbConfigration.getDbName();
            String user = dbConfigration.getUsername();
            String password = dbConfigration.getPassword();
            String port = dbConfigration.getPort();
            String dbNameKey = host + dbName;
            if (DATA_SOURCES_MAP.get(dbNameKey) != null) {
                return DATA_SOURCES_MAP.get(dbNameKey);
            } else {
                HashMap<String, String> map = new HashMap<>();
                map.put("url", String.format("jdbc:mysql://%s:%s/%s%s",host,port,dbName,JDBC_CONNECT_PARAM));
                map.put("username", user);
                map.put("password", password);
                map.put("type", "com.zaxxer.hikari.HikariDataSource");
                map.put("driver-class-name", "com.mysql.cj.jdbc.Driver");
                // 创建连接池
                DataSource dataSource = DruidDataSourceFactory.createDataSource(map);
                DATA_SOURCES_MAP.put(dbNameKey, dataSource);
                return dataSource;
            }
        }catch (Exception e) {
            return null;
        }
    }

    @Override
    public void afterPropertiesSet() {}


    public static String getLoginNameKey() {
        return LOGIN_NAME_KEY.get();
    }

    public static void setLoginNameKey(String loginName) {
        clear();
        LOGIN_NAME_KEY.set(loginName);
    }

    /**
     * 清空缓存
     */
    public static void clearDataSourcesMap() {
        DATA_SOURCES_MAP.clear();
    }

    /**
     * 清空当前线程变量
     */
    public static void clear() {
        LOGIN_NAME_KEY.remove();
    }
}
